import * as Joi from '@hapi/joi';
import { Module, OnModuleInit } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppConfigValidationSchema } from './config/app.env.schema';
import { MinioConfigValidationSchema } from './config/minio.env.schema';
import { PgConfigValidationSchema } from './config/pg.env.schema';
import { UserModule } from './modules/user/user.module';
import { MediaModule } from './modules/media/media.module';
import { PostModule } from './modules/post/post.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthModule } from './modules/auth/auth.module';
import { APP_FILTER, APP_INTERCEPTOR, HttpAdapterHost } from '@nestjs/core';
import { HttpFilter } from './filters/http.filter';
import { LogTimeInterceptor } from './interceptors/log-time.interceptor';

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: [
        'env/local.app.env',
        'env/local.minio.env',
        'env/local.pg.env',
      ],
      validationSchema: Joi.object({
        AppConfigValidationSchema,
        ...MinioConfigValidationSchema,
        ...PgConfigValidationSchema,
      }),
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get('DB_HOST'),
        port: +configService.get('DB_PORT'),
        username: configService.get('DB_USERNAME'),
        password: configService.get('DB_PASSWORD'),
        database: configService.get('DB_NAME'),
        // entities: [],
        autoLoadEntities: true,
        synchronize: true,
      }),
    }),
    UserModule,
    MediaModule,
    PostModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_INTERCEPTOR,
      useFactory(configService: ConfigService) {
        return new LogTimeInterceptor(configService);
      },
      inject: [ConfigService],
    },
    {
      provide: APP_FILTER,
      useFactory(
        httpAdapterHost: HttpAdapterHost,
        configService: ConfigService,
      ) {
        return new HttpFilter(httpAdapterHost, configService);
      },
      inject: [HttpAdapterHost, ConfigService],
    },
  ],
})
export class AppModule {}
